// #pragma once

// #include <iostream>
// #include <unistd.h>
// #include <ctime>
// #include <cstdarg>
// #include <fstream>
// #include <cstring>
// #include <pthread.h>
// #include "lockguard.hpp"


// namespace log_namespace
// {
//     enum
//     {
//         DEBUG = 1,
//         INFO,
//         WARNING,
//         ERROR,
//         FATAL
//     };

//     std::string levelToString(int level)
//     {
//         switch(level)
//         {
//             case DEBUG:
//                 return "DEBUG";
//             case INFO:
//                 return "INFO";
//             case WARNING:
//                 return "WARNING";
//             case ERROR:
//                 return "ERROR";
//             case FATAL:
//                 return "FATAL";
//             default:
//                 return "UNKNOWN";
//         }
//     }

//     std::string getCurtime()
//     {
//         time_t now = time(nullptr);
//         struct tm *currtime = localtime(&now);
//         char buffer[128];
//         snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", \
//             currtime->tm_hour,\
//             currtime->tm_min,\
//             currtime->tm_sec
//             );
//         return buffer;
//     }

//     class logmessage
//     {
//     public:
//         std::string _level;
//         pid_t  _id;
//         std::string _filename;
//         int _filenumber;
//         std::string _curtime;
//         std::string _msginfo;
//     };

//     #define SCREEN_TYPE 1
//     #define FILE_TYPE 2

//     const std::string glogfile = "./log.txt";
//     pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;

//     class Log
//     {
//     private:
//         int _type;
//         const std::string _logfile;
//     public:
//         Log(const std::string &logfile = glogfile)
//             :_type(SCREEN_TYPE)
//             ,_logfile(logfile)
//         {

//         }

//         void enable(int type)
//         {
//             _type = type;
//         }

//         void flushLogToScreen(const logmessage& lg)
//         {
//             printf("[%s][%d][%s][%d][%s] %s", 
//                 lg._level.c_str(),
//                 lg._id,
//                 lg._filename.c_str(),
//                 lg._filenumber,
//                 lg._curtime.c_str(),
//                 lg._msginfo.c_str()
//             );
//         }

//         void flushLogToFile(const logmessage& lg)
//         {
//             // std::ios::app代表写文件是以 append模式进行的

//             std::ofstream out(_logfile, std::ios::app);
//             if (!out.is_open())
//             {
//                 return;
//             }

//             char logtxt[2048];
//             snprintf(logtxt, sizeof(logtxt), "[%s][%d][%s][%d][%s] %s", 
//                 lg._level.c_str(),
//                 lg._id,
//                 lg._filename.c_str(),
//                 lg._filenumber,
//                 lg._curtime.c_str(),
//                 lg._msginfo.c_str()
//             );

//             out.write(logtxt, strlen(logtxt));
//             out.close();
//         }

//         void flushLog(const logmessage& lg)
//         {
//             lockGuard lguard(&glock);

//             switch(_type)
//             {
//                 case SCREEN_TYPE:
//                     flushLogToScreen(lg);
//                     break;
//                 case FILE_TYPE:
//                     flushLogToFile(lg);
//                     break;
//             }
//         }

//         void logMessage(std::string filename, int filenumber, int level, const char *format, ...)
//         {
//             logmessage lg;
//             lg._level = levelToString(level);
//             lg._id = getpid();
//             lg._filename = filename;
//             lg._filenumber = filenumber;
//             lg._curtime = getCurtime();

//             va_list ap;
//             va_start(ap, format);
//             char log_info[1024];
//             vsnprintf(log_info, sizeof(log_info), format, ap);
//             va_end(ap);
//             lg._msginfo = log_info;

//             flushLog(lg);
//         }

//         ~Log()
//         {

//         }

//     };

//     Log lg;

//     // __FILE__ 就是当前文件的文件路径，__LINE__就是当前文件的行号
//     // 其中 do{} while(0) 单纯是为了保护下面定义的这个宏中的代码块的安全性
//     // 其中##__VA_ARGS__就是为了防止传入空时，Format后面的那个逗号仍然存在
//     #define LOG(Level, Format, ...) do{\
//         lg.logMessage(__FILE__, __LINE__, Level, Format, ##__VA_ARGS__);\
//     }while(0)

//     #define EnableScreen() do{lg.enable(SCREEN_TYPE); } while(0)
//     #define EnableFILE() do{lg.enable(FILE_TYPE); } while(0)

// };